home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 2 / Atari Mega Archive CD - Volume 2.iso / minix / up1510b.tgz / up1510b / src / fs / misc.c < prev    next >
C/C++ Source or Header  |  1990-07-23  |  8KB  |  280 lines

  1. /* This file contains a collection of miscellaneous procedures.  Some of them
  2.  * perform simple system calls.  Some others do a little part of system calls
  3.  * that are mostly performed by the Memory Manager.
  4.  *
  5.  * The entry points into this file are
  6.  *   do_dup:    perform the DUP system call
  7.  *   do_fcntl:    perform the FCNTL system call
  8.  *   do_sync:    perform the SYNC system call
  9.  *   do_fork:    adjust the tables after MM has performed a FORK system call
  10.  *   do_exit:    a process has exited; note that in the tables
  11.  *   do_set:    set uid or gid for some process
  12.  *   do_revive:    revive a process that was waiting for something (e.g. TTY)
  13.  */
  14.  
  15. #include "fs.h"
  16. #include <fcntl.h>
  17. #include <minix/callnr.h>
  18. #include <minix/com.h>
  19. #include <minix/boot.h>
  20. #include "buf.h"
  21. #include "file.h"
  22. #include "fproc.h"
  23. #include "inode.h"
  24. #include "param.h"
  25. #include "super.h"
  26.  
  27. /*===========================================================================*
  28.  *                do_dup                         *
  29.  *===========================================================================*/
  30. PUBLIC int do_dup()
  31. {
  32. /* Perform the dup(fd) or dup(fd,fd2) system call. */
  33.  
  34.   register int rfd;
  35.   register struct filp *f;
  36.   struct filp *dummy;
  37.   int r;
  38.  
  39.   /* Is the file descriptor valid? */
  40.   rfd = fd & ~DUP_MASK;        /* kill off dup2 bit, if on */
  41.   if ((f = get_filp(rfd)) == NIL_FILP) return(err_code);
  42.  
  43.   /* Distinguish between dup and dup2. */
  44.   if (fd == rfd) {            /* bit not on */
  45.     /* dup(fd) */
  46.     if ( (r = get_fd(0, 0, &fd2, &dummy)) != OK) return(r);
  47.   } else {
  48.     /* dup2(fd, fd2) */
  49.     if (fd2 < 0 || fd2 >= OPEN_MAX) return(EBADF);
  50.     if (rfd == fd2) return(fd2);    /* ignore the call: dup2(x, x) */
  51.     fd = fd2;        /* prepare to close fd2 */
  52.     (void) do_close();    /* cannot fail */
  53.   }
  54.  
  55.   /* Success. Set up new file descriptors. */
  56.   f->filp_count++;
  57.   fp->fp_filp[fd2] = f;
  58.   return(fd2);
  59. }
  60.  
  61. /*===========================================================================*
  62.  *                do_fcntl                     *
  63.  *===========================================================================*/
  64. PUBLIC int do_fcntl()
  65. {
  66. /* Perform the fcntl(fd, request, addr) system call. */
  67.  
  68.   register struct filp *f;
  69.   int new_fd, r, fl;
  70.   struct filp *dummy;
  71.  
  72.   /* Is the file descriptor valid? */
  73.   if ((f = get_filp(fd)) == NIL_FILP) return(err_code);
  74.  
  75.   switch (request) {
  76.      case F_DUPFD: 
  77.     /* DUP */
  78.     if (addr < 0 || addr >= OPEN_MAX) break;
  79.     if ((r = get_fd(addr, 0, &new_fd, &dummy)) != OK) return(r);
  80.        f->filp_count++;
  81.       fp->fp_filp[new_fd] = f;
  82.       return(new_fd);
  83.  
  84.      case F_GETFD: 
  85.     /* Get close-on-exec flag. */
  86.     break;    
  87.  
  88.      case F_SETFD: 
  89.     /* Set close-on-exec flag. */
  90.     break;    
  91.  
  92.      case F_GETFL: 
  93.     /* Get file status flags. */
  94.     return(f->filp_flags);    
  95.  
  96.      case F_SETFL: 
  97.     /* Set file status flags. */
  98.     fl = O_NONBLOCK | O_APPEND;
  99.     f->filp_flags = (f->filp_flags & ~fl) | (addr & fl);
  100.     return(OK);
  101.  
  102.      case F_GETLK:
  103.      case F_SETLK:
  104.      case F_SETLKW:
  105.     printf("do_fcntl: flag not yet implemented\n");
  106.   }
  107.   return(EINVAL);
  108. }
  109.  
  110.  
  111. /*===========================================================================*
  112.  *                do_sync                         *
  113.  *===========================================================================*/
  114. PUBLIC int do_sync()
  115. {
  116. /* Perform the sync() system call.  Flush all the tables. */
  117.  
  118.   register struct inode *rip;
  119.   register struct buf *bp;
  120.   register struct super_block *sp;
  121.  
  122.   /* The order in which the various tables are flushed is critical.  The
  123.    * blocks must be flushed last, since rw_inode() and rw_super() leave their
  124.    * results in the block cache.
  125.    */
  126.  
  127.   /* Update the time in the root super_block. */
  128.   sp = get_super(ROOT_DEV);
  129.   if (sp != NIL_SUPER) {
  130.       sp->s_time = clock_time();
  131.       if (sp->s_rd_only == FALSE) sp->s_dirt = DIRTY;
  132.   }
  133.  
  134.   /* Write all the dirty inodes to the disk. */
  135.   for (rip = &inode[0]; rip < &inode[NR_INODES]; rip++)
  136.     if (rip->i_count > 0 && rip->i_dirt == DIRTY) rw_inode(rip, WRITING);
  137.  
  138.   /* Write all the dirty super_blocks to the disk. */
  139.   for (sp = &super_block[0]; sp < &super_block[NR_SUPERS]; sp++)
  140.     if (sp->s_dev != NO_DEV && sp->s_dirt == DIRTY) rw_super(sp, WRITING);
  141.  
  142.   /* Write all the dirty blocks to the disk, one drive at a time. */
  143.   for (bp = &buf[0]; bp < &buf[NR_BUFS]; bp++)
  144.     if (bp->b_dev != NO_DEV && bp->b_dirt == DIRTY) flushall(bp->b_dev);
  145.  
  146.   return(OK);        /* sync() can't fail */
  147. }
  148.  
  149.  
  150. /*===========================================================================*
  151.  *                do_fork                         *
  152.  *===========================================================================*/
  153. PUBLIC int do_fork()
  154. {
  155. /* Perform those aspects of the fork() system call that relate to files.
  156.  * In particular, let the child inherit its parent's file descriptors.
  157.  * The parent and child parameters tell who forked off whom. The file
  158.  * system uses the same slot numbers as the kernel.  Only MM makes this call.
  159.  */
  160.  
  161.   register struct fproc *cp;
  162.   register char *sptr, *dptr;
  163.   int i;
  164.  
  165.   /* Only MM may make this call directly. */
  166.   if (who != MM_PROC_NR) return(ERROR);
  167.  
  168.   /* Copy the parent's fproc struct to the child. */
  169.   sptr = (char *) &fproc[parent];    /* pointer to parent's 'fproc' struct */
  170.   dptr = (char *) &fproc[child];    /* pointer to child's 'fproc' struct */
  171.   i = sizeof(struct fproc);        /* how many bytes to copy */
  172.   while (i--) *dptr++ = *sptr++;    /* fproc[child] = fproc[parent] */
  173.  
  174.   /* Increase the counters in the 'filp' table. */
  175.   cp = &fproc[child];
  176.   for (i = 0; i < OPEN_MAX; i++)
  177.     if (cp->fp_filp[i] != NIL_FILP) cp->fp_filp[i]->filp_count++;
  178.  
  179.   /* Fill in new process id and, if necessary, process group. */
  180.   cp->fp_pid = pid;
  181.   if (parent == INIT_PROC_NR) {
  182.     cp->fp_pgrp = pid;
  183.   }
  184.  
  185.   /* Record the fact that both root and working dir have another user. */
  186.   dup_inode(cp->fp_rootdir);
  187.   dup_inode(cp->fp_workdir);
  188.   return(OK);
  189. }
  190.  
  191.  
  192. /*===========================================================================*
  193.  *                do_exit                         *
  194.  *===========================================================================*/
  195. PUBLIC int do_exit()
  196. {
  197. /* Perform the file system portion of the exit(status) system call. */
  198.  
  199.   register int i, exitee, task;
  200.  
  201.   /* Only MM may do the EXIT call directly. */
  202.   if (who != MM_PROC_NR) return(ERROR);
  203.  
  204.   /* Nevertheless, pretend that the call came from the user. */
  205.   fp = &fproc[slot1];        /* get_filp() needs 'fp' */
  206.   exitee = slot1;
  207.  
  208.   /* Can this be a process group leader associated with a terminal? */
  209.   if (fp->fp_pid == fp->fp_pgrp && fp->fs_tty != 0) tty_exit();
  210.  
  211.   if (fp->fp_suspended == SUSPENDED) {
  212.     task = -fp->fp_task;
  213.     if (task == XPIPE || task == XOPEN) susp_count--;
  214.     pro = exitee;
  215.     do_unpause();
  216.     fp->fp_suspended = NOT_SUSPENDED;
  217.   }
  218.  
  219.   /* Loop on file descriptors, closing any that are open. */
  220.   for (i=0; i < OPEN_MAX; i++) {
  221.     fd = i;
  222.     (void) do_close();
  223.   }
  224.  
  225.   /* Release root and working directories. */
  226.   put_inode(fp->fp_rootdir);
  227.   put_inode(fp->fp_workdir);
  228.   fp->fp_rootdir = NIL_INODE;
  229.   fp->fp_workdir = NIL_INODE;
  230.  
  231.   return(OK);
  232. }
  233.  
  234.  
  235. /*===========================================================================*
  236.  *                do_set                         *
  237.  *===========================================================================*/
  238. PUBLIC int do_set()
  239. {
  240. /* Set uid_t or gid_t field. */
  241.  
  242.   register struct fproc *tfp;
  243.  
  244.   /* Only MM may make this call directly. */
  245.   if (who != MM_PROC_NR) return(ERROR);
  246.  
  247.   tfp = &fproc[slot1];
  248.   if (fs_call == SETUID) {
  249.     tfp->fp_realuid = (uid_t) real_user_id;
  250.     tfp->fp_effuid =  (uid_t) eff_user_id;
  251.   }
  252.   if (fs_call == SETGID) {
  253.     tfp->fp_effgid =  (gid_t) eff_grp_id;
  254.     tfp->fp_realgid = (gid_t) real_grp_id;
  255.   }
  256.   return(OK);
  257. }
  258.  
  259.  
  260. /*===========================================================================*
  261.  *                do_revive                     *
  262.  *===========================================================================*/
  263. PUBLIC int do_revive()
  264. {
  265. /* A task, typically TTY, has now gotten the characters that were needed for a
  266.  * previous read.  The process did not get a reply when it made the call.
  267.  * Instead it was suspended.  Now we can send the reply to wake it up.  This
  268.  * business has to be done carefully, since the incoming message is from
  269.  * a task (to which no reply can be sent), and the reply must go to a process
  270.  * that blocked earlier.  The reply to the caller is inhibited b